# @FileName  :  signup.py
# @Time      :  2025/7/28 22:34
# @Author    :  Ayanami
# @info      :  报名相关的API接口

from typing import Optional
from fastapi import APIRouter, HTTPException, Query, Path
from app.schemas.signup import (
    SignUpCreate,
    SignUpUpdate,
    SignUpResponse,
    SignUpWithDetailsResponse,
    EnrollmentRecordCreate,
    EnrollmentRecordResponse,
    EnrollmentRecordWithDetailsResponse,
    PaginatedSignUpResponse,
    PaginatedEnrollmentResponse
)
from app.crud.signup import SignUpCRUD, EnrollmentRecordCRUD

router = APIRouter(tags=["报名管理"])


# 报名相关接口
# 报名记录相关接口
@router.post("/enrollments", response_model=EnrollmentRecordResponse, summary="学员报名")
async def create_enrollment(enrollment: EnrollmentRecordCreate):
    """学员报名课程"""
    try:
        created_enrollment = await EnrollmentRecordCRUD.create(enrollment)
        return EnrollmentRecordResponse.model_validate(created_enrollment)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"报名失败: {str(e)}")


@router.get("/enrollments", response_model=PaginatedEnrollmentResponse, summary="获取报名记录列表")
async def get_enrollments(
        page: int = Query(1, ge=1, description="页码"),
        page_size: int = Query(10, ge=1, le=100, description="每页数量"),
        signup_id: Optional[int] = Query(None, description="报名ID"),
        student_id: Optional[int] = Query(None, description="学员ID"),
        course_id: Optional[int] = Query(None, description="课程ID")
):
    """获取报名记录列表，支持分页和筛选"""
    try:
        enrollments, total = await EnrollmentRecordCRUD.get_list(
            page=page,
            page_size=page_size,
            signup_id=signup_id,
            student_id=student_id,
            course_id=course_id
        )

        return PaginatedEnrollmentResponse(
            items=enrollments,
            total=total,
            page=page,
            page_size=page_size,
            has_next=page * page_size < total,
            has_prev=page > 1
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取报名记录失败: {str(e)}")


@router.get("/enrollments/{enrollment_id}", response_model=EnrollmentRecordWithDetailsResponse,
            summary="获取报名记录详情")
async def get_enrollment(
        enrollment_id: int = Path(..., description="报名记录ID")
):
    """根据ID获取报名记录详细信息"""
    enrollment = await EnrollmentRecordCRUD.get_by_id_with_details(enrollment_id)
    if not enrollment:
        raise HTTPException(status_code=404, detail="报名记录不存在")
    return enrollment


@router.delete("/enrollments/{enrollment_id}", summary="取消报名")
async def cancel_enrollment(
        enrollment_id: int = Path(..., description="报名记录ID")
):
    """取消学员报名"""
    try:
        deleted = await EnrollmentRecordCRUD.delete(enrollment_id)
        if not deleted:
            raise HTTPException(status_code=404, detail="报名记录不存在")
        return {"message": "取消报名成功"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"取消报名失败: {str(e)}")


@router.get("/enrollments/check/{student_id}/{signup_id}", response_model=EnrollmentRecordResponse,
            summary="检查报名状态")
async def check_enrollment_status(
        student_id: int = Path(..., description="学员ID"),
        signup_id: int = Path(..., description="报名ID")
):
    """检查学员是否已报名指定课程"""
    enrollment = await EnrollmentRecordCRUD.get_by_student_and_signup(student_id, signup_id)
    if not enrollment:
        raise HTTPException(status_code=404, detail="未找到报名记录")
    return EnrollmentRecordResponse.model_validate(enrollment)

@router.post("/", response_model=SignUpResponse, summary="创建报名")
async def create_signup(signup: SignUpCreate):
    """创建新的报名"""
    try:
        created_signup = await SignUpCRUD.create(signup)
        return SignUpResponse.model_validate(created_signup)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"创建报名失败: {str(e)}")


@router.get("/", response_model=PaginatedSignUpResponse, summary="获取报名列表")
async def get_signups(
        page: int = Query(1, ge=1, description="页码"),
        page_size: int = Query(10, ge=1, le=100, description="每页数量"),
        course_id: Optional[int] = Query(None, description="课程ID"),
        status: Optional[str] = Query(None, regex="^(upcoming|ongoing|ended)$", description="状态筛选")
):
    """获取报名列表，支持分页和筛选"""
    try:
        signups, total = await SignUpCRUD.get_list(
            page=page,
            page_size=page_size,
            course_id=course_id,
            status=status
        )

        return PaginatedSignUpResponse(
            items=signups,
            total=total,
            page=page,
            page_size=page_size,
            has_next=page * page_size < total,
            has_prev=page > 1
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取报名列表失败: {str(e)}")


@router.get("/{signup_id}", response_model=SignUpWithDetailsResponse, summary="获取报名详情")
async def get_signup(
        signup_id: int = Path(..., description="报名ID")
):
    """根据ID获取报名详细信息"""
    signup = await SignUpCRUD.get_by_id_with_details(signup_id)
    if not signup:
        raise HTTPException(status_code=404, detail="报名不存在")
    return signup


@router.put("/{signup_id}", response_model=SignUpResponse, summary="更新报名")
async def update_signup(
        signup_id: int = Path(..., description="报名ID"),
        signup_update: SignUpUpdate = ...
):
    """更新报名信息"""
    try:
        updated_signup = await SignUpCRUD.update(signup_id, signup_update)
        if not updated_signup:
            raise HTTPException(status_code=404, detail="报名不存在")
        return SignUpResponse.model_validate(updated_signup)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"更新报名失败: {str(e)}")


@router.delete("/{signup_id}", summary="删除报名")
async def delete_signup(
        signup_id: int = Path(..., description="报名ID")
):
    """删除报名"""
    try:
        deleted = await SignUpCRUD.delete(signup_id)
        if not deleted:
            raise HTTPException(status_code=404, detail="报名不存在")
        return {"message": "删除成功"}
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"删除报名失败: {str(e)}")





@router.get("/{signup_id}/stats", summary="获取报名统计信息")
async def get_signup_stats(
        signup_id: int = Path(..., description="报名ID")
):
    """获取报名的统计信息"""
    signup = await SignUpCRUD.get_by_id(signup_id)
    if not signup:
        raise HTTPException(status_code=404, detail="报名不存在")

    try:
        # 获取统计信息
        total_enrollments = await EnrollmentRecordCRUD.get_list(signup_id=signup_id)
        current_count = total_enrollments[1]  # 总数

        return {
            "signup_id": signup_id,
            "max_capacity": signup.max_capacity,
            "current_enrollment_count": current_count,
            "available_spots": signup.max_capacity - current_count,
            "enrollment_rate": round((current_count / signup.max_capacity) * 100, 2) if signup.max_capacity > 0 else 0,
            "is_full": current_count >= signup.max_capacity
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取统计信息失败: {str(e)}")